'use strict';

module.exports = core;

const path = require('path')
const semver = require('semver')
const colors = require('colors')
const userHome = require('user-home')
const pathExists = require('path-exists').sync
const commander = require('commander')
const log = require('@alic-cli-dev/log')
const exec = require('@alic-cli-dev/exec')
const pkg = require('../package.json')
const constants = require('./constants')

let args, config;

const program = new commander.Command()

async function core() {
    try {
        await prepare()
        registerCommand()
    } catch(e) {
        log.error(e.message);
    }
}

function registerCommand() {
    program
        .name(Object.keys(pkg.bin)[0])
        .usage('<command> [options]')
        .version(pkg.version)
        .option('-d, --debug', '是否开启调试模式', false)
        .option('-tp, --targetPath <targetPath>', '是否指定本地调试文件路径', '')
        .option('-bu, --baseUrl <baseUrl>', '是否指定请求路径', '')

    program
        .command('init [projectName]')
        .option('-f, --force', '是否强制初始化项目')
        .action(exec)
    program
        .command('rename [updateName] [newName]')
        .option('-f, --force', '是否强制更改名字')
        .action(exec)

    program
        .command('publish')
        .option('-rs, --refreshServer', '强制更新远程git仓库')
        .option('-rt, --refreshToken', '强制更新远程仓库token')
        .option('-ro, --refreshOwner', '强制更新远程仓库类型')
        .option('-bc, --buildCmd [buildCmd]', '构建命令')
        .option('-p, --prod', '是否正式发布')
        .action(exec)
    program.on('option:debug', function() {
        if(program.debug) {
            process.env.LOG_LEVEL = 'verbose'
        } else {
            process.env.LOG_LEVEL = 'info'
        }
        log.level = process.env.LOG_LEVEL
    })
    program.on('option:targetPath', function() {
        process.env.CLI_TARGET_PATH = program.targetPath
    })
    program.on('option:baseUrl', function() {
        process.env.CLI_BASE_URL = program.baseUrl
    })

    
    program.on('command:*', function(obj) {
        const availableCommands = program.commands.map(cmd => cmd.name())
        console.log(colors.red('未知的命令：' + obj[0]))
        if(availableCommands.length > 0) {
            console.log(colors.red('可用命令：' + availableCommands.join(',')))
        }
    })
    program.parse(process.argv)
    if(program.args && program.args.length < 1) {
        program.outputHelp()
        console.log()
    }
}

async function prepare() {
    checkPkgVersion()
    // checkNodeVersion()
    checkRoot()
    checkUserHome()
    // checkInputArgs()
    checkEnv()
    await checkGlobalUpdate()
}

async function checkGlobalUpdate() {
    const currentVersion = pkg.version
    const npmName = pkg.name
    const { getNpmSemverVersion } = require('@alic-cli-dev/get-npm-info');
    const lastVersion = await getNpmSemverVersion(currentVersion, npmName)
    if(lastVersion && semver.gt(lastVersion, currentVersion)) {
        log.warn('更新提示', colors.yellow(`请手动更新 ${npmName}，当前版本${currentVersion}，最新版本：${lastVersion}
更新命令：npm install -g ${npmName}`))
    }
}

function checkEnv() {
    const dotEnv = require('dotenv');
    const dotenvPath = path.resolve(userHome, '.env');
    if(pathExists(dotenvPath)) {
        dotEnv.config({
            path: dotenvPath
        });
    }
    config = createDefaultConfig()
    log.verbose('环境变量', process.env.CLI_HOME_PATH);
}

function createDefaultConfig() {
    const cliConfig = {
        home: userHome,
    }
    if(process.env.CLI_HOME) {
        cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME)
    } else {
        cliConfig['cliHome'] = path.join(userHome, constants.DEFAULT_CLI_HOME)
    }
    process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

function checkInputArgs() {
    const minimist = require('minimist')
    args = minimist(process.argv.slice(2))
    checkArgs(args)
}

function checkArgs() {
    if(args.debug) {
        process.env.LOG_LEVEL = 'verbose'
    } else {
        process.env.LOG_LEVEL = 'info'
    }
    log.level = process.env.LOG_LEVEL
}

function checkNodeVersion() {
    const currentVersion = process.version;
    const lowestVersion = constants.LOWEST_NODE_VERSION
    if(!semver.gte(currentVersion, lowestVersion)) {
        throw new Error(colors.red(`alic-cli 需要安装 v${lowestVersion} 以上版本的 Node.js`))
    }
}

function checkRoot() {
    const rootCheck = require('root-check')
    rootCheck();
}

function checkUserHome() {
    if(!userHome || !pathExists(userHome)) {
        throw new Error(colors.red('当前登录用户主目录不存在！'))
    }
}

function checkPkgVersion() {
    log.notice(pkg.version)
}
